package com.hhd.flow.engine.cmd.impl;

import com.hhd.flow.engine.utils.CommonUtils;
import com.hhd.flow.engine.utils.FlowUtils;
import com.hhd.flow.engine.variable.FlowVariablesContainer;
import com.hhd.flow.entity.FlowProcessInstance;
import com.hhd.flow.entity.FlowUserDone;
import com.hhd.flow.entity.FlowUserTaskHistory;
import com.hhd.flow.service.IFlowUserDoneService;
import com.hhd.flow.service.IFlowUserTaskHistoryService;
import lombok.experimental.SuperBuilder;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@SuperBuilder(toBuilder = true)
public abstract class FlowDoneCommand<T> extends AbstractCommand<T> {
    private IFlowUserDoneService flowUserDoneService;
    private IFlowUserTaskHistoryService flowUserTaskHistoryService;

    protected void clearFlowUserDone(String formId) {
        flowUserDoneService = getEngine().getFlowUserDoneService();
        flowUserDoneService.lambdaUpdate()
                .eq(FlowUserDone::getFormId, formId)
                .remove();
    }

    protected void forFlowUserDone(String formId) {
        clearFlowUserDone(formId);
        flowUserTaskHistoryService = getEngine().getFlowUserTaskHistoryService();

        List<FlowUserTaskHistory> taskHistories = flowUserTaskHistoryService.lambdaQuery()
                .eq(FlowUserTaskHistory::getFormId, formId)
                .orderByDesc(FlowUserTaskHistory::getCompleteTime, FlowUserTaskHistory::getCreateTime)
                .list();

        Set<String> userIds = new HashSet<>();
        List<FlowUserDone> flowUserDones = taskHistories.stream().filter(taskHistory -> {
                    if (userIds.contains(taskHistory.getUserId())) return false;
                    userIds.add(taskHistory.getUserId());
                    return true;
                }).map(this::createFlowUserDone)
                .collect(Collectors.toList());
        if (!CommonUtils.isEmpty(taskHistories)) {
            flowUserDoneService.saveBatch(flowUserDones);
        }
    }

    private FlowUserDone createFlowUserDone(FlowUserTaskHistory flowUserTaskHistory) {
       return FlowUtils.createFlowUserDone(flowUserTaskHistory);
    }
}
